<template>
  <view v-if="tempFilePath" class="card">
    <view class="title">已录制</view>
    <view class="app-between">
      <view class="app-between player" @click="playBtn">
        <u-icon
          v-if="playStatus === 0"
          class="icon-play"
          name="volume"
        ></u-icon>
        <u-icon
          v-if="playStatus !== 0"
          class="icon-play"
          name="volume-off"
        ></u-icon>

        <!-- <image
          class="icon-play"
          :src="
            playStatus === 0
              ? '/static/icon/icon-play.png'
              : '/static/icon/icon-stop.png'
          "
        >
        </image> -->
        <u-icon
          class="icon-sound"
          name="volume-fill"
          color="#cccccc"
          size="42rpx"
        ></u-icon>
        <!-- <image class="icon-sound" src="/static/icon/icon-sound.png"></image> -->
        <text class="time">{{ getVoiceDuration }}</text>
      </view>
      <u-icon
        name="trash"
        color="#cccccc"
        size="42rpx"
        @click="delBtn"
      ></u-icon>
    </view>
  </view>

  <view v-if="longPress == 2" class="prompt-layer">
    <view class="prompt-popup">
      <view class="p">{{ "剩余：" + count + "s" }}</view>
      <view style="font-size: 42rpx; margin-top: 30rpx">松手 完成</view>
    </view>
  </view>

  <up-button
    class="sbmit-btn"
    type="default"
    @longpress="longpressBtn"
    @touchend="touchendBtn"
  >
    <text class="inner"></text>
  </up-button>
</template>

<script setup lang="ts">
import { ref, reactive, computed } from "vue";
import { onLoad } from "@dcloudio/uni-app";

const recordAuth = ref(false); // 是否授权录音

// 录音
const recorderManager = uni.getRecorderManager(); // 录音管理对象
let init: any = null; // 录制时长计时器
let timer: any = null; // 播放 录制倒计时
const count = ref(0); // 录制倒计时
const longPress = ref(1); // 1显示 按住说话 2显示 说话中

function recordingTimer(_time: any) {
  if (_time == undefined) {
    // 将计时器赋值给init
    init = setInterval(() => {
      time.value++;
    }, 1000);
  } else {
    clearInterval(init);
  }
}

// 录音授权
function authorRecord() {
  uni.authorize({
    scope: "scope.record", //这里选择scope.(录音、位置、用户信息...都可以)
    success() {
      // 允许授权
      console.log("已授权");
      recordAuth.value = true;
    },
    fail() {
      // 拒绝授权
      uni.showModal({
        content: "检测到您没打开录音功能权限，是否去设置打开？",
        confirmText: "确认",
        confirmColor: "#1874f5",
        cancelText: "取消",
        success: (res) => {
          if (res.confirm) {
            uni.openSetting({
              // opensetting 是调起设置页面的
              success: (res) => {
                // 获取设置授权的状态
                const setting = res.authSetting;
                recordAuth.value = setting["scope.record"] || false;
              },
            });
          } else {
            return false;
          }
        },
      });
      return false;
    },
  });
}

// 长按录音事件
function longpressBtn() {
  if (!recordAuth.value) {
    authorRecord();
    return;
  }
  longPress.value = 2;
  clearInterval(init); // 清除定时器
  countdown(60); // 倒计时
  recorderManager.onStop((res) => {
    tempFilePath.value = res.tempFilePath;
    recordingTimer(time.value);
  });
  const options = {
    duration: duration.value, // 指定录音的时长，单位 ms
    sampleRate: 16000, // 采样率
    numberOfChannels: 1, // 录音通道数
    encodeBitRate: 96000, // 编码码率
    format: "mp3", // 音频格式，有效值 aac/mp3
    frameSize: 10, // 指定帧大小，单位 KB
  };
  recordingTimer(undefined);
  recorderManager.start(options);
  // 监听音频开始事件
  recorderManager.onStart((res) => {
    console.log(res);
  });
}

// 长按松开录音事件
function touchendBtn() {
  if (!recordAuth.value) {
    return;
  }

  longPress.value = 1;
  recorderManager.onStop((result) => {
    // 录音结束，可以先调用删除接口将旧录音删除，然后再上传最新的录音
    // 通过 uni.uploadFile 上传录音文件，filePath 传 voice.tempFilePath，指定要上传文件资源路径
    // 下面是示例，模拟上传成功之后的处理
    tempFilePath.value =
      "https://web-ext-storage.dcloud.net.cn/uni-app/ForElise.mp3";
    innerAudioContext.src =
      "https://web-ext-storage.dcloud.net.cn/uni-app/ForElise.mp3";
    time.value = 30;
    voiceAllTime.value = time.value;
  });
  recordingTimer(time.value);
  clearInterval(timer);
  recorderManager.stop();
}

// 音频
const innerAudioContext = uni.createInnerAudioContext(); // audio 上下文对象
const time = ref(0); //录音时长
const duration = ref(60000); //录音最大值ms 60000/1分钟
const tempFilePath: any = ref(""); //音频路径
const playStatus = ref(0); //录音播放状态 0:未播放 1:正在播放
const voiceAllTime = ref(0); //记录音频原始总时长

// 显示音频剩余秒数
const getVoiceDuration = computed(() => {
  let _t = String(time.value);
  let str = _t.length > 1 ? `00:${_t}` : `00:0${_t}`;
  return str;
});

// 播放
function updateTime(val: number) {
  time.value = Number(val);
  timer = setInterval(() => {
    if (time.value >= 1) {
      time.value--;
    } else {
      time.value = voiceAllTime.value;
      clearInterval(timer);
    }
  }, 1000);
}
function playBtn() {
  //点击播放
  if (playStatus.value == 0) {
    playStatus.value = 1;
    innerAudioContext.play();
    updateTime(time.value); // 倒计时
  } else {
    playStatus.value = 0;
    innerAudioContext.pause();
    clearInterval(timer);
  }
  //播放结束
  innerAudioContext.onEnded(() => {
    playStatus.value = 0;
  });
}

// 删除录音
function delBtn() {
  // 调用接口删除
  // 下面是示例，删除后的重置
  time.value = 0;
  tempFilePath.value = "";
  playStatus.value = 0;
  time.value = voiceAllTime.value = 0;
}

// 倒计时
function countdown(val: any) {
  count.value = Number(val);
  timer = setInterval(() => {
    if (count.value > 0) {
      count.value--;
    } else {
      longPress.value = 1;
      clearInterval(timer);
    }
  }, 1000);
}

// 获取录音权限状态
function getRecordSetting() {
  uni.getSetting({
    success(res) {
      const setting = res.authSetting;
      recordAuth.value = setting["scope.record"] || false;
    },
  });
}

// 设置录音
function setVoice() {
  // 进入页面时调用接口获取上传的路由文件路径
  // 下面是示例
  tempFilePath.value =
    "https://web-ext-storage.dcloud.net.cn/uni-app/ForElise.mp3";
  innerAudioContext.src = tempFilePath.value;
  time.value = 30;
  voiceAllTime.value = time.value;
}

onLoad(() => {
  setVoice();

  getRecordSetting();
});
</script>

<style lang="scss" scoped>
.card {
  margin: 0 0 24rpx;
  padding: 100rpx 24rpx;
  background: #ffffff;

  .title {
    margin-bottom: 16rpx;
    color: #333333;
    font-size: 28rpx;
    font-weight: 700;
  }

  .desc {
    color: #666666;
    font-size: 24rpx;
    font-weight: 400;
  }

  .app-tags {
    .tag {
      padding: 12rpx 24rpx;
      border-radius: 28rpx;
      color: #666666;
      font-size: 24rpx;
      font-weight: 400;
      background: #f8f8f8;
    }
  }

  .player {
    padding: 8rpx 16rpx 8rpx 8rpx;
    width: 354rpx;
    height: 64rpx;
    border-radius: 40rpx;
    background: #f8f8f8;

    .icon-play {
      width: 48rpx;
      height: 48rpx;
    }

    .icon-sound {
      width: 172rpx;
      height: 32rpx;
    }

    .time {
      color: #666666;
      font-size: 24rpx;
      font-weight: 400;
    }
  }
}

.sbmit-btn {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 114rpx;
  margin: auto;
  border-radius: 50%;
  width: 152rpx;
  height: 152rpx;
  background: #666666;
  box-shadow: 0 0 32rpx 0 #bababa40;
  z-index: 1;

  &::after {
    border: none;
  }

  .inner {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
    border-radius: 50%;
    width: 52rpx;
    height: 52rpx;
    background: #ffffff;
  }
}

.prompt-layer {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.4);
  z-index: 5;

  .prompt-popup {
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 220rpx;
    // line-height: 200rpx;
    color: #000000;
    font-size: 28rpx;
    font-weight: 400;
    text-align: center;

    &::after {
      content: "";
      position: absolute;
      left: -10%;
      bottom: -52%;
      border-radius: 50%; //顶部圆弧，底部圆弧： 0 0 50% 50%
      width: 120%;
      height: 185%;
      background: #cccccc;
      z-index: -1;
    }
  }
}
</style>
